package homework.service;

import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Random;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

import static homework.tools.FunctionalTrait.*;

// 存放图片的路径需要手动创建出来; @MultipartConfig里可以配置上传文件相关约束

@WebServlet(name="uploadImage", urlPatterns={ "/upload-image" })
@MultipartConfig
public class UploadImage extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		letIf(req.getPart("file"), (part) -> part != null, (part) -> {
			let(decorate(part, RichPart::new), (richpart) -> {
				System.out.println(richpart.partInfo());
				String imgPath = "/upload-images";
				String filename = richpart.saveAndGet(getServletContext().getRealPath(imgPath));
				try { resp.getWriter().write("/homework-upload/upload-images/" + filename); resp.flushBuffer();	} catch (IOException e) { }	
			});
		}, (part) -> {
			try { resp.getWriter().write("/homework-upload/upload-images/default.jpg"); resp.flushBuffer();	} catch (IOException e) { }	
		});
	}
	
	private static class RichPart {
		private final Part part;
		public RichPart(Part part) { this.part = part; }
		public String partInfo() {
			return part.getHeaderNames()
					   .stream()
					   .map((name) -> String.format("%s: %s", name, part.getHeader(name)))
					   .collect(Collectors.joining(", "));
		}
		public String fileName() {
			return either(Pattern.compile("filename=\"(.*)\"$").matcher(part.getHeader("content-disposition")), 
					(matcher) -> matcher.find(), 
					(matcher) -> matcher.group(1), 
					(matcher) -> "");
		}
		public String typeName() {
			return either(fileName(), 
					(filename) -> filename.equals(""), 
					(filename) -> "",
					(filename) -> either(Pattern.compile("\\.[^.]+?$").matcher(filename), 
							(matcher) -> matcher.find(), 
							(matcher) -> matcher.group(0), 
							(matcher) -> ""));
		}
		public String saveAndGet(String path) { // 一个 _ 不行 你需要两个; 同时stream第一个元素是 "" 需要跳过去 ...
			String type = typeName();
			String legalName = Stream.iterate("", (__) -> LocalizeHelper.randomFileName(32) + type)
									 .skip(1)
								     .filter((name) -> !new File(path + "\\" + name).exists()) 
								     .findFirst()
								     .get();
			try { part.write(path + "\\" + legalName); } catch (IOException e) { e.printStackTrace(); }
			return legalName;
		}
	}

	private static class LocalizeHelper {
		private static final String pool = "0123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP";
		private static final Random random = new Random(Calendar.getInstance().getTimeInMillis());
		private LocalizeHelper() { }
		private static String randomFileName(int nameLength) {
			return random.ints(nameLength, 0, pool.length()).mapToObj((i) -> pool.substring(i, i + 1)).collect(Collectors.joining()); // 用 substring 因为 charAt 返回值不是 String ...
		}
	}
}
